[BITS 32]

[global start]
[extern k_main] ; this is in the c file
[extern k_isr_unhandled]
[extern k_isr_timer]
[extern k_isr_keyboard]

start:
  ; stop using bootloader GDT, and load new GDT
  lgdt [gdt_desc]

  mov ax,LINEAR_DATA_SEL
  mov ds,ax
  mov es,ax
  mov ss,ax
  mov fs,ax
  mov gs,ax

	; Set stack pointer
	mov esp, sys_stack

	cld
	mov ax,LINEAR_DATA_SEL
	mov es,ax
	xor eax,eax
	xor ecx,ecx
	mov edi,0x200

	; install blank isrs
	mov ax,256
loop_idt:
	lea esi,[idt_unhandled]
	mov ecx,8
	rep movsb
	dec ax
	jnz loop_idt

	; install timer ISR
	mov edi,0x200+(8*32)
	lea esi,[idt_timer]
	mov ecx,8
	rep movsb

	; install keyboard ISR
	mov edi,0x200+(8*33)
	lea esi,[idt_keyboard]
	mov ecx,8
	rep movsb

	; Program the PIC
	; ICW1 - Initialize
	mov al,0x11
	out 0x20,al
	out 0xA0,al
	; ICW2 - IRQ offset
	mov al,0x20
	out 0x21,al
	mov al,0x28
	out 0xA1,al
	; ICW3 - Master-Slave connection
	mov al,0x04
	out 0x21,al
	mov al, 0x02
	out 0xA1,al
	; ICW4 - 8086 mode
	mov al,0x01
	out 0x21,al
	out 0xA1,al
	; PIC mask - none
	mov al,0x0
	out 0x21,al
	out 0xA1,al

	lidt [idt_desc]

	sti

  call k_main

  jmp $ ; crash

isr_unhandled:
	pusha
	call k_isr_unhandled
	popa
	iret

isr_timer:
	pusha
	call k_isr_timer
	mov al,0x20
	out 0x20,al
	popa
	iret

isr_keyboard:
	pusha
	call k_isr_keyboard
	mov al,0x20
	out 0x20,al
	popa
	iret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SECTION .data

gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
        dd 0
        dd 0

LINEAR_CODE_SEL	equ	$-gdt
gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0FFFFh
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

LINEAR_DATA_SEL	equ	$-gdt
gdt_data:               ; Data segment, read/write, expand down
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0

gdt_end:                ; Used to calculate the size of the GDT


gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd gdt                  ; Address of the GDT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

idt_unhandled:
	dw isr_unhandled
	dw LINEAR_CODE_SEL
	db 0
	db 0x8E
	dw 0x0000

idt_timer:
	dw isr_timer
	dw LINEAR_CODE_SEL
	db 0
	db 0x8E
	dw 0x0000

idt_keyboard:
	dw isr_keyboard
	dw LINEAR_CODE_SEL
	db 0
	db 0x8E
	dw 0x0000


idt_desc:
	dw 256*8-1
	dd 0x200

SECTION .bss
	resb 8192
sys_stack:

